]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
loginManager: Use systemd session auto object to get session ID
authorAlessandro Bono <alessandro.bono369@gmail.com>
Thu, 30 Oct 2025 10:47:17 +0000 (11:47 +0100)
committerAlessandro Bono <alessandro.bono369@gmail.com>
Thu, 30 Oct 2025 11:07:07 +0000 (12:07 +0100)
Relying on the Display property is buggy when the gdm user spawns more than
one gnome-shell instance.
```
$ loginctl
SESSION  UID USER   SEAT  LEADER CLASS         TTY   IDLE SINCE
     11   42 gdm    -     11778  manager-early -     no   -
    c20   42 gdm    seat0 34313  greeter       tty1  yes  17h ago
    c21   42 gdm    -     34938  greeter       -     no   -
    c22   42 gdm    -     35693  greeter       -     no   -
```

From the logs:
```
$ journalctl -b | grep "Will monitor"
[...]
Oct 29 15:14:59 gnome-shell[34961]: Will monitor session c20
Oct 29 15:22:57 gnome-shell[35716]: Will monitor session c20
Oct 29 15:22:58 gnome-shell[35716]: Will monitor session c20
```

Use the systemd session auto object for getting the session id. We can't return
directly the session proxy created from it because it won't emit signals. From
the documentation[1]:
```
Signals are only emitted on objects referencing a specific session ID not on the
"/org/freedesktop/login1/session/self" or "/org/freedesktop/login1/session/auto"
convenience objects, as they can only be dereferenced relative to a method caller.
```

[1] https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.login1.html

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3942>

js/misc/loginManager.js

index 86f17479e81c85dd3f5a4a2b1f57c3ec5b6ec540..a93e0cb5d53b62f3219cfa74c036c0beb7003207 100644 (file)
@@ -127,33 +127,17 @@ class LoginManagerSystemd extends Signals.EventEmitter {
         let sessionId = GLib.getenv('XDG_SESSION_ID');
         if (!sessionId) {
             log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session. Asking logind directly.');
-            const userProxy = await this.getCurrentUserProxy();
-            let [session, objectPath] = userProxy.Display;
-            if (session) {
-                log(`Will monitor session ${session}`);
-                sessionId = session;
-            } else {
-                log('Failed to find "Display" session; are we the greeter?');
-
-                for ([session, objectPath] of userProxy.Sessions) {
-                    const sessionProxy = new SystemdLoginSession(Gio.DBus.system,
-                        'org.freedesktop.login1',
-                        objectPath);
-                    log(`Considering ${session}, class=${sessionProxy.Class}`);
-                    if (sessionProxy.Class === 'greeter') {
-                        log(`Yes, will monitor session ${session}`);
-                        sessionId = session;
-                        break;
-                    }
-                }
-
-                if (!sessionId) {
-                    log('No, failed to get session from logind.');
-                    return null;
-                }
+            try {
+                const autoSession = await SystemdLoginSession.newAsync(
+                    Gio.DBus.system, 'org.freedesktop.login1', '/org/freedesktop/login1/session/auto');
+                sessionId = autoSession.Id;
+            } catch (error) {
+                logError(error, 'Failed to get session from logind');
+                return null;
             }
         }
 
+        log(`Will monitor session ${sessionId}`);
         try {
             const [objectPath] = await this._proxy.GetSessionAsync(sessionId);
             this._currentSession = await SystemdLoginSession.newAsync(